package com.iwinding.ladygg.bluetooth.impblekit;

import android.bluetooth.BluetoothGatt;
import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.util.Log;

import com.amap.api.location.AMapLocation;
import com.iwinding.ladygg.bluetooth.TMApi;
import com.iwinding.ladygg.bluetooth.bean.BleDevice;
import com.iwinding.ladygg.bluetooth.ibluetooth.IAnalysis;
import com.iwinding.ladygg.bluetooth.ibluetooth.IAutoBlelimit;
import com.iwinding.ladygg.constant.BluetoothConstants;
import com.iwinding.ladygg.utils.AMMapHelper;
import com.iwinding.ladygg.utils.GsonUtil;
import com.iwinding.ladygg.utils.HexStringUtil;
import com.iwinding.ladygg.utils.LogUtil;
import com.inuker.bluetooth.library.model.BleGattProfile;
import com.inuker.bluetooth.library.model.BleGattService;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.iwinding.ladygg.bluetooth.MyGattAttributes.SERVICE_FEATURES;
import static com.iwinding.ladygg.bluetooth.MyGattAttributes.SERVICE_NAME;

/**
 * Created by 82218 on 2017/7/13.
 */

public class ICaneBleApi implements IAutoBlelimit, IAnalysis {


    private static final String LASTCONNDEVICENAME = "lastConnDeviceName";

    private static ExecutorService mExecutorService;

    static {
        mExecutorService = Executors.newCachedThreadPool();
    }

    /**
     * 内部类实现单例模式
     * 延迟加载，减少内存开销
     *
     * @author xuzhaohu
     */
    private static final class SingletonHolder {
        private static final ICaneBleApi instance = new ICaneBleApi();
    }

    public static ICaneBleApi getInstance() {
        return SingletonHolder.instance;
    }

    public void initContext(Context mContext) {
        this.mContext = mContext;
        TMApi.getInstance().initContext(mContext);
        initAutoDevice();
    }

    private Context mContext;
    private boolean handshake;
    private boolean press;
    private boolean alarm;
    private boolean tips;
    private int volume;
    private int tempVolume;

    private List<BleDevice> deviceList = new ArrayList<>();//设备列表,连接过的设备
    private List<BleDevice> noActiveDeviceList = new ArrayList<>();//未激活的设备

    public boolean isHandshake() {
        return handshake;
    }

    public void setHandshake(boolean handshake) {
        this.handshake = handshake;
    }

    public boolean isPress() {
        return press;
    }

    public void setPress(boolean press) {
        this.press = press;
    }

    public boolean isAlarm() {
        return alarm;
    }

    public void setAlarm(boolean alarm) {
        this.alarm = alarm;
    }

    public boolean isTips() {
        return tips;
    }

    public void setTips(boolean tips) {
        this.tips = tips;
    }

    public int getVolume() {
        return volume;
    }

    public void setVolume(int volume) {
        this.volume = volume;
    }

    @Override
    public String getServiceName() {
        return SERVICE_NAME;
    }

    @Override
    public String getServiceFeatures() {
        return SERVICE_FEATURES;
    }

    boolean isAutoBle = true;

    @Override
    public boolean isNeedAutoConnect() {
        return isAutoBle;
    }

    public void setNeedAutoConnect(boolean autoBle) {
        isAutoBle = autoBle;
    }

    @Override
    public void connDoSomethings(BleDevice device, BluetoothGatt gatt) {
//        BluetoothGattService iCaneService = gatt.getService(UUID.fromString(getServiceName()));
//        List<BluetoothGattService> list = gatt.getServices();
//        if (iCaneService != null) {
//            BluetoothGattCharacteristic characteristic = iCaneService.getCharacteristic(UUID.fromString(MyGattAttributes.SERVICE_FEATURES));
//            if (characteristic != null) {
//                BleManager.getInstance().setCharacteristic(characteristic);
//                BleManager.getInstance().writeBle(getServiceName(), getServiceFeatures(), cmdHandshake());
//                return;
//            }
//        }
//        BleManager.getInstance().disConnetBle();
    }

    boolean isAllow = false;

    public void setAllow(boolean allow) {
        isAllow = allow;
    }

    @Override
    public void connDoSomethings(BleDevice device, BleGattProfile profile) {
//        List<BleGattService> services = profile.getServices();
//        for (BleGattService service : services) {
//            if (!TextUtils.equals(getServiceName(), service.getUUID().toString().toUpperCase())) {
//                continue;
//            }
//            List<BleGattCharacter> characters = service.getCharacters();
//            for (BleGattCharacter character : characters) {
//                if (TextUtils.equals(getServiceFeatures(), character.getUuid().toString().toUpperCase())) {
//                    BleKitManager.getInstance().writeBle(getServiceName(), getServiceFeatures(), cmdHandshake());
//                    return;
//                }
//            }
//        }

        BleGattService service = profile.getService(UUID.fromString(getServiceName()));
        if (service != null) {
            device.uuid = getServiceName();
            BleKitManager.getInstance().writeBle(getServiceName(), getServiceFeatures(), cmdHandshake());
            addAutoDevice(device);
            return;
        }
//        if (!isAllow) {
//            BleKitManager.getInstance().disConnetBle();
//        }
    }

    @Override
    public void addAutoDevice(BleDevice device) {
        if (null == device) {
            return;
        }
        final int oldSize = deviceList.size();
        if (oldSize == 0) {
            deviceList.add(0, device);
        } else {
            boolean ishas = false;
            for (BleDevice bleDevice : deviceList) {
                if (TextUtils.equals(bleDevice.deviceAddress, device.deviceAddress)) {
                    ishas = true;
                    continue;
                }
            }
            if (!ishas) {
                deviceList.add(0, device);
            }
        }
        final int newSize = deviceList.size();
        if (newSize > oldSize) {
            SharedPreferences sp = mContext.getSharedPreferences("BLE", Context.MODE_APPEND);
            String json = GsonUtil.getInstance().jsonToList(deviceList);
            sp.edit().putString(LASTCONNDEVICENAME, json).commit();
            sp.edit().clear();
        }
    }

    private int index = -1;

    @Override
    public BleDevice getNextAutoDevice() {
        if (deviceList.size() == 0) {
            return null;
        }
        if (index == (deviceList.size() - 1)) {
            index = -1;
        }
        index++;
        return deviceList.get(index);
    }

    @Override
    public List<BleDevice> getAutoDevices() {
        return deviceList;
    }

    @Override
    public void setActiveBleDevice(BleDevice device, boolean isActive) {
        if (!isActive) {
            noActiveDeviceList.add(device);
        } else {
            if (noActiveDeviceList.contains(device)) {
                noActiveDeviceList.remove(device);
            }
        }
    }

    @Override
    public boolean isActiveBleDevice(BleDevice device) {
        if (noActiveDeviceList.contains(device)) {
            return false;
        }
        return true;
    }

    @Override
    public int getMaxAutoCount() {
        return deviceList.size();
    }

    public void initAutoDevice() {
        SharedPreferences sp = mContext.getSharedPreferences("BLE", Context.MODE_APPEND);
        String json = sp.getString(LASTCONNDEVICENAME, "");
        if (TextUtils.isEmpty(json)) {
            return;
        }
        List<BleDevice> mTemp = GsonUtil.getInstance().jsonToArray(json, BleDevice.class);
        deviceList.clear();
        deviceList.addAll(mTemp);
    }


    //握手
    public byte[] cmdHandshake() {
        return cmdGeneral(HexStringUtil.charToByteString(BluetoothConstants.CMD.CMD_HANDSHAKE));
    }

    //回复按钮状态
    public byte[] cmdKey3Press() {
        return cmdGeneral(HexStringUtil.charToByteString(BluetoothConstants.CMD.CMD_KEY3));
    }

    //回复角度信息
    public byte[] cmdDirection() {
        return cmdGeneral(HexStringUtil.charToByteString(BluetoothConstants.CMD.CMD_DIRECTION_ANGLE));
    }

    //回复电量
    public byte[] cmdPower() {
        return cmdGeneral(HexStringUtil.charToByteString(BluetoothConstants.CMD.CMD_POWER));
    }

    //修改音量
    public byte[] cmdVolume(int volume) {
        tempVolume = volume;
        return cmdGeneral(HexStringUtil.charToByteString(BluetoothConstants.CMD.CMD_VOLUME_MODIFY), new byte[]{(byte) volume});
    }

    private byte[] cmdGeneral(byte cmd, byte[] status) {
        return createCmd(cmd, status);
    }

    private byte[] cmdGeneral(byte cmd) {
        return createCmd(cmd, new byte[]{0x00});
    }

    //创建命令
    public byte[] createCmd(byte cmd, byte[] status) {
        byte[] send = new byte[16];

        send[0] = HexStringUtil.charToByteString(BluetoothConstants.CMD.CMD_HEAD);
        send[1] = HexStringUtil.charToByteString(BluetoothConstants.CMD.CMD_MID);
        send[2] = cmd;
        if (status != null && status.length < 12) {
            int j = 3;
            for (int i = 0; i < status.length; i++) {
                j = j + i;
                send[j] = status[i];
            }
            j = j + status.length;
            for (; j < 15; j++) {
                send[j] = 0x00;
            }
        }
        send[15] = HexStringUtil.charToByteString(BluetoothConstants.CMD.CMD_END);
        return send;
    }

    /**
     * 解析
     *
     * @param bytes
     */
    public void analysis(byte[] bytes) {
        String cmd = HexStringUtil.bytesToHexString(new byte[]{bytes[2]});
        switch (cmd) {
            case BluetoothConstants.CMD.CMD_HANDSHAKE:
                analysisHandshake(bytes);
                break;
            case BluetoothConstants.CMD.CMD_KEY3:
                analysisKey3(bytes);
                applyIcane(cmdKey3Press());
                break;
            case BluetoothConstants.CMD.CMD_DIRECTION_ANGLE:
                analysisDirection(bytes);
                applyIcane(cmdDirection());
                break;
            case BluetoothConstants.CMD.CMD_POWER:
                analysisPower(bytes);
                applyIcane(cmdPower());
                break;
            case BluetoothConstants.CMD.CMD_VOLUME_MODIFY_RE://0xff
                analysisVolume();
                break;
        }
    }

    /**
     * 解析握手命令返回
     *
     * @param bytes
     */
    public void analysisHandshake(byte[] bytes) {
        handshake = getHandshakeStatus(bytes[3]);
        press = getKey3Press(bytes[4]);
        alarm = getAlarmStatus(bytes[5]);
        tips = getBatteryTips(bytes[6]);
        volume = bytes[7];
        Log.i("@hzy", "handshake------------" + handshake);
        Log.i("@hzy", "press------------" + press);
        Log.i("@hzy", "alarm------------" + alarm);
        Log.i("@hzy", "tips------------" + tips);
        Log.i("@hzy", "volume------------" + volume);
        setVolume(volume);
        onDirection(alarm);
        onPress(press);
    }

    /**
     * 解析Key3命令
     *
     * @param bytes
     */
    public void analysisKey3(byte[] bytes) {
        press = getKey3Press(bytes[3]);
        onPress(press);
    }

    /**
     * 解析角度命令
     *
     * @param bytes
     */
    public void analysisDirection(byte[] bytes) {
        alarm = getAlarmStatus(bytes[3]);
        onDirection(alarm);
    }

    /**
     * 解析电量命令
     *
     * @param bytes
     */
    public void analysisPower(byte[] bytes) {
        tips = getBatteryTips(bytes[3]);
    }

    /**
     * 解析音量
     */
    public void analysisVolume() {
        volume = tempVolume;
    }

    public void onDirection(boolean alarm) {
        if (!handshake) {
            return;
        }
        if (alarm) {
            LogUtil.i("@hzy", "-----------alarm");
            mExecutorService.execute(new Runnable() {
                @Override
                public void run() {
                    AMMapHelper.getInstance().startLocation();
                    AMapLocation locationInfo = AMMapHelper.getInstance().getmLocationInfo();
                    TMApi.getInstance().sendSOS(locationInfo);
                }
            });
        }
    }

    public void onPress(boolean press) {
        if (!handshake) {
            return;
        }
        if (press) {
            LogUtil.i("@hzy", "-----------press");
            mExecutorService.execute(new Runnable() {
                @Override
                public void run() {
                    AMMapHelper.getInstance().startLocation();
                    AMapLocation locationInfo = AMMapHelper.getInstance().getmLocationInfo();
                    TMApi.getInstance().sendSOS(locationInfo);
                }
            });
        }
    }

    /**
     * 获取握手状态
     *
     * @param status
     * @return
     */
    boolean getHandshakeStatus(int status) {
        return status == BluetoothConstants.DeviceStatus.HANDSHAKE_OK;
    }

    /**
     * key3按钮按下状态
     *
     * @param status
     * @return
     */
    boolean getKey3Press(int status) {
        return status == BluetoothConstants.DeviceStatus.KEY3_PRESS;
    }

    /**
     * 报警提示
     *
     * @param status
     * @return
     */
    boolean getAlarmStatus(int status) {
        return status == BluetoothConstants.DeviceStatus.DIRECTION_ALARM;
    }

    /**
     * 电量提示
     *
     * @param status
     * @return
     */
    boolean getBatteryTips(int status) {
        return status == BluetoothConstants.DeviceStatus.LOW_BATTERY_TIPS;
    }

    private void applyIcane(byte[] cmd) {
        Log.i("@hzy", "-------applyIcane" + cmd);
        String serviceName = ICaneBleApi.getInstance().getServiceName();
        String serviceFeatures = ICaneBleApi.getInstance().getServiceFeatures();
        BleKitManager.getInstance().writeBle(serviceName, serviceFeatures, cmd);
    }

}
